void SetBits(ULONG_PTR& dw, int lowBit, int bits, int newValue)
{
	ULONG_PTR mask = (1 << bits) - 1; 
	dw = (dw & ~(mask << lowBit)) | (newValue << lowBit);
}

static ULONG NTAPI BreakHandler(LPVOID lpParameter)
{
	ULONG PrevSuspend;
	LONG PrevState;
	HWBRK* h = (HWBRK*)lpParameter;
	if(NT_SUCCESS(NtSuspendThread(h->hThread,&PrevSuspend)))
	{
		CONTEXT ct = {0};
		ct.ContextFlags = CONTEXT_DEBUG_REGISTERS;
		if(NT_SUCCESS(NtGetContextThread(h->hThread,&ct)))
		{
			int FlagBit = 0;
			bool Dr0Busy = false;
			bool Dr1Busy = false;
			bool Dr2Busy = false;
			bool Dr3Busy = false;
			if (ct.Dr7 & 1)
				Dr0Busy = true;
			if (ct.Dr7 & 4)
				Dr1Busy = true;
			if (ct.Dr7 & 16)
				Dr2Busy = true;
			if (ct.Dr7 & 64)
				Dr3Busy = true;
			if (h->Opr == 1)
			{
				if (h->iReg == 0)
				{
					FlagBit = 0;
					ct.Dr0 = 0;
					Dr0Busy = false;
				}
				if (h->iReg == 1)
				{
					FlagBit = 2;
					ct.Dr1 = 0;
					Dr1Busy = false;
				}
				if (h->iReg == 2)
				{
					FlagBit = 4;
					ct.Dr2 = 0;
					Dr2Busy = false;
				}
				if (h->iReg == 3)
				{
					FlagBit = 6;
					ct.Dr3 = 0;
					Dr3Busy = false;
				}
				ct.Dr7 &= ~(1 << FlagBit);
			}
			else
			{
				if (!Dr0Busy)
				{
					h->iReg = 0;
					ct.Dr0 = (ULONG)h->BreakAddress;
					Dr0Busy = true;
				}
				else if (!Dr1Busy)
				{
					h->iReg = 1;
					ct.Dr1 = (ULONG)h->BreakAddress;
					Dr1Busy = true;
				}
				else if (!Dr2Busy)
				{
					h->iReg = 2;
					ct.Dr2 = (ULONG)h->BreakAddress;
					Dr2Busy = true;
				}
				else if (!Dr3Busy)
				{
					h->iReg = 3;
					ct.Dr3 = (ULONG)h->BreakAddress;
					Dr3Busy = true;
				}
				else
				{
					h->SUCC = false;
					NtResumeThread(h->hThread,&PrevSuspend);
					NtSetEvent(h->hEvent,&PrevState);
					return 0;
				}
				ct.Dr6 = 0;
				int st = 0;
				if (h->Type == HWBRK_TYPE_CODE)
				{
					st = 0;
				}
				if (h->Type == HWBRK_TYPE_READWRITE)
				{
					st = 3;
				}
				if (h->Type == HWBRK_TYPE_WRITE)
				{
					st = 1;
				}
				int le = 0;
				if (h->Size == HWBRK_SIZE_1)
				{
					le = 0;
				}
				if (h->Size == HWBRK_SIZE_2)
				{
					le = 1;
				}
				if (h->Size == HWBRK_SIZE_4)
				{
					le = 3;
				}
				if (h->Size == HWBRK_SIZE_8)
				{
					le = 2;
				}
				SetBits(ct.Dr7, 16 + h->iReg*4, 2, st);
				SetBits(ct.Dr7, 18 + h->iReg*4, 2, le);
				SetBits(ct.Dr7, h->iReg*2,1,1);
			}
			ct.ContextFlags = CONTEXT_DEBUG_REGISTERS;
			if(NT_SUCCESS(NtSetContextThread(h->hThread,&ct)))
			{
				ct.ContextFlags = CONTEXT_DEBUG_REGISTERS;
				NtGetContextThread(h->hThread,&ct);
    			NtResumeThread(h->hThread,&PrevSuspend);
				h->SUCC = true;
				NtSetEvent(h->hEvent,&PrevState);
				return 0;
			}
			else
			{
				NtResumeThread(h->hThread,&PrevSuspend);
				h->SUCC = false;
				NtSetEvent(h->hEvent,&PrevState);
				return 1;
			
			}
		}
		else
		{
			NtResumeThread(h->hThread,&PrevSuspend);
			h->SUCC = false;
			NtSetEvent(h->hEvent,&PrevState);
			return 1;
		}
	}
	return 1;
}

HANDLE SetHardwareBreakpoint(HANDLE hThread,HWBRK_TYPE Type,HWBRK_SIZE Size,void* lpBreakAddress)
{
	HWBRK* h = {0};
	CLIENT_ID ClientId = {0};
	HANDLE hBreakMng;
	h->BreakAddress = lpBreakAddress;
	h->Size = Size;
	h->Type = Type;
	h->hThread = hThread;
	if (hThread == NtCurrentThread())
	{
		ClientId.UniqueProcess = 0;
		ClientId.UniqueThread = (HANDLE)NtCurrentThreadId();
		if(!NT_SUCCESS(NtOpenThread(&h->hThread,THREAD_ALL_ACCESS,0,&ClientId)))
		{
			return INVALID_HANDLE_VALUE;
		}
	}
	if(NT_SUCCESS(NtCreateEvent(&h->hEvent,0,0,NotificationEvent,false)))
	{
		h->Opr = 0; // Set Break
		if(NT_SUCCESS(RtlCreateUserThread(NtCurrentProcess(),0,false,0,0,0,(PUSER_THREAD_START_ROUTINE)BreakHandler,(PVOID)&h,&hBreakMng,&ClientId)))
		{
			NtWaitForSingleObject(h->hEvent,false,0);
			NtClose(h->hEvent);
			h->hEvent = 0;
			return (HANDLE)h;
		}
		else
		{
			NtClose(h->hThread);
			NtClose(h->hEvent);
			h->hEvent = 0;
			return INVALID_HANDLE_VALUE;
		}
	}
	else
	{
		NtClose(h->hThread);
		return INVALID_HANDLE_VALUE;
	}
}


__checkReturn  bool RemoveHardwareBreakpoint(__in HANDLE hBrk)
{
	HWBRK* h = (HWBRK*)hBrk;
	HANDLE hBreakMng;
	CLIENT_ID ClientId;
	if (!h)
	{
		return false;
	}
	bool C = false;
	if (h->hThread == NtCurrentThread())
	{
		ClientId.UniqueProcess = 0;
		ClientId.UniqueThread = (HANDLE)NtCurrentThreadId();
		if(NT_SUCCESS(NtOpenThread(&h->hThread,THREAD_ALL_ACCESS,0,&ClientId)))
		{
			C = (h->hThread != INVALID_HANDLE_VALUE) ? true : false;
		}
	}
	if(NT_SUCCESS(NtCreateEvent(&h->hEvent,0,0,NotificationEvent,0)))
	{
		h->Opr = 1; // Remove Break
		if(NT_SUCCESS(RtlCreateUserThread(NtCurrentProcess(),0,0,0,0,0,(PUSER_THREAD_START_ROUTINE)BreakHandler,(PVOID)&h,&hBreakMng,&ClientId)))
		{
			NtWaitForSingleObject(h->hEvent,false,0);
			NtClose(h->hEvent);
			h->hEvent = 0;
			if(C)
			{
				NtClose(h->hThread);
			}
			return true;
		}
		else
		{
			NtClose(h->hEvent);
			return false;
		}
	}
	return false;
}
//FindCode returns address of code
//params 
//1 dwStart is Start address of scan ie a return from GetProcAddress or GetApi..
//2	4 byte array 
//ckBase [0] = first byte to check
//ckBase [1] = second byte to check if first byte is correct
//ckBase [2] = third is offset to add to the Start to find the second opcode
//if the next instruction is the one you want to check this should be 0..
//ckBase [3] = after finding the after the code u want to find minus a 
//offset of 4 to read that address 

/*Example RtlAddVectoredExceptionHandler RtlpVehListHead
...
7C936C98   . E8 7AC7FDFF    CALL ntdll.RtlEncodePointer
7C936C9D   . BF E005987C    MOV EDI,ntdll.7C9805E0
7C936CA2   . 57             PUSH EDI
7C936CA3   . 8946 08        MOV DWORD PTR DS:[ESI+8],EAX
7C936CA6   . E8 55A3FCFF    CALL ntdll.RtlEnterCriticalSection
7C936CAB   . 837D 08 00     CMP DWORD PTR SS:[EBP+8],0
7C936CAF   . 0F84 10D80000  JE ntdll.7C9444C5
7C936CB5   . A1 C0E3977C    MOV EAX,DWORD PTR DS:[7C97E3C0];so we want this address 
7C936CBA   . 8906           MOV DWORD PTR DS:[ESI],EAX 
we want to find these opcodes to read 0x8906.. 
so call setup would look like
BYTE FindThis[4] = {0x89,0x06,0,0x4};
RtlpVehListHead = FindCode((ULONG)GetProcAddress(GetModuleHandle(_T"ntdll.dll"),/
_T"RtlAddVectoredExceptionHandler"),&FindThis);
InsertHeadList()
*/
ULONG FindCode(__in ULONG dwStart,__in BYTE *FindThis)
{
	
	ULONG ProcEnd = 0;					
	ProcEnd = GetFunctionLength((void*)dwStart);
	ProcEnd += dwStart;
	do
	{
		if(memcmp((void*)dwStart,&FindThis[0],sizeof(BYTE)) == 0 && memcmp((void*)(dwStart+sizeof(BYTE)+(ULONG)FindThis[2]),&FindThis[1],sizeof(BYTE)) == 0)
		{
			return (ULONG)(dwStart - (ULONG)FindThis[3]);
		}
		(BYTE*)dwStart++;
	}while(dwStart < ProcEnd);
	ProcEnd = 0;
	return ProcEnd;
}
HANDLE GetPidByName(wchar_t *pstrProcessName)
{
	UNICODE_STRING dbgMessage = {0};
	NTSTATUS Status = 0;
	SIZE_T cbBuffer = 0x8000;
	PVOID pBuffer = NULL;
	HANDLE hResult = NULL;
	PSYSTEM_PROCESS_INFORMATION_EX pProcesses = {0};
	WCHAR *pszProcessName = 0;
	do
	{
		pBuffer = (void *)RtlAllocateHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0, cbBuffer);
		if (pBuffer == NULL)
		{
			return 0;
		}
		Status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)5,pBuffer,cbBuffer, NULL);
		if(Status == 0xC0000004)
		{
			RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap, 0, pBuffer);
			cbBuffer *= 2;
		}
	}while (Status == 0xC0000004);
	pProcesses = (PSYSTEM_PROCESS_INFORMATION_EX)pBuffer;
	for (;;)
	{
		if((ULONG)pProcesses->ImageName.Buffer != 0xbaadf00d && pProcesses->ImageName.Buffer != 0)
		{
			pszProcessName = pProcesses->ImageName.Buffer;
		}
		else
		{
			pszProcessName = L"";
		}
		if (pszProcessName == NULL)
		{
			pszProcessName = L"Idle";
		}
		if(wcscmp(pszProcessName, pstrProcessName) == 0)
		{
			hResult = (HANDLE)pProcesses->UniqueProcessId;
			break;
		}
		if (pProcesses->NextEntryOffset == 0)break;
		{
			pProcesses = (PSYSTEM_PROCESS_INFORMATION_EX)(((BYTE *)pProcesses)+pProcesses->NextEntryOffset);
		}
	}
	RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap, 0, pBuffer);
	return hResult;
}
void DbgOutput(UNICODE_STRING*Unicode,NTSTATUS Status)
{
	wchar_t Err[255] = {0};
	_ultow(Status,(wchar_t*)&Err,16);
	DbgPrint("%ws %ws\r\n",Unicode->Buffer,&Err);
	return;
}
void __declspec(naked) CatchInit(void)
{
	__asm
	{
		nop	//0
		nop	//1
		nop	//2
		nop	//3
		nop	//4
		nop	//5
		nop	//6
		nop	//7
		nop	//8
		nop	//9
		nop	//a
		nop	//b
		nop	//c
		nop	//d
		nop	//e
		nop	//f
		nop	//10
		nop	//11
		nop	//12
		nop	//13
		nop	//14
		nop	//15
		nop	//16
		nop	//17
		nop	//18
		nop	//19
		nop	//1a
		nop	//1b
		nop	//1c
		nop	//1d
		nop	//1e
		nop	//1f
		nop	//20
		nop	//21
		nop	//22
		nop	//23
		nop	//24
		nop	//25
		nop	//26
		nop	//27
		nop	//28
		nop	//29
		nop	//2a
		nop	//2b
		nop	//2c
		nop	//2d
		nop	//2e
		nop	//2f
		nop	//30
		nop	//31
		nop //32
		nop	//33
		nop	//34
		nop	//35
		nop	//36
		nop	//37
		nop	//38
		nop	//39
		nop	//3a
		nop	//3b
		nop	//3c
		nop	//3d
		nop	//3e
		nop	//3f
		nop	//40
		nop //41
		nop //42
		nop //43
		nop //45
		nop //46
		nop //47
		nop //48
		nop //49
		nop //4a
		nop //4b
		nop //4c
		nop //4d
		nop //4e
		nop //4f
		nop //50
		nop //51
		nop //52
		nop //53
		nop //54
		nop //55
		nop //56
		nop //57
		nop //58
		nop //59
		nop //5a
		nop //5b
		nop //5c
		nop //5d
		nop //5e
		nop //5f
		nop //60
		nop //61
		nop //62
		nop //63
		nop //64
		nop //65
		nop //66
		nop //67
		nop //68
		nop //69
		nop //6a
		nop //6b
		nop //6c
		nop //6d
		nop //6e
		nop //6f
		nop //70
		nop //71
		nop //72
		nop //73
		nop //74
		nop //75
		nop //76
		nop //77
		nop //78
		nop //79
		nop //7a
		nop //7b
		nop //7c
		nop //7d
		nop //7e
		nop //7f
		nop //80
		nop	//0
		nop	//1
		nop	//2
		nop	//3
		nop	//4
		nop	//5
		nop	//6
		nop	//7
		nop	//8
		nop	//9
		nop	//a
		nop	//b
		nop	//c
		nop	//d
		nop	//e
		nop	//f
		nop	//10
		nop	//11
		nop	//12
		nop	//13
		nop	//14
		nop	//15
		nop	//16
		nop	//17
		nop	//18
		nop	//19
		nop	//1a
		nop	//1b
		nop	//1c
		nop	//1d
		nop	//1e
		nop	//1f
		nop	//20
		nop	//21
		nop	//22
		nop	//23
		nop	//24
		nop	//25
		nop	//26
		nop	//27
		nop	//28
		nop	//29
		nop	//2a
		nop	//2b
		nop	//2c
		nop	//2d
		nop	//2e
		nop	//2f
		nop	//30
		nop	//31
		nop //32
		nop	//33
		nop	//34
		nop	//35
		nop	//36
		nop	//37
		nop	//38
		nop	//39
		nop	//3a
		nop	//3b
		nop	//3c
		nop	//3d
		nop	//3e
		nop	//3f
		nop	//40
		nop //41
		nop //42
		nop //43
		nop //45
		nop //46
		nop //47
		nop //48
		nop //49
		nop //4a
		nop //4b
		nop //4c
		nop //4d
		nop //4e
		nop //4f
		nop //50
		nop //51
		nop //52
		nop //53
		nop //54
		nop //55
		nop //56
		nop //57
		nop //58
		nop //59
		nop //5a
		nop //5b
		nop //5c
		nop //5d
		nop //5e
		nop //5f
		nop //60
		nop //61
		nop //62
		nop //63
		nop //64
		nop //65
		nop //66
		nop //67
		nop //68
		nop //69
		nop //6a
		nop //6b
		nop //6c
		nop //6d
		nop //6e
		nop //6f
		nop //70
		nop //71
		nop //72
		nop //73
		nop //74
		nop //75
		nop //76
		nop //77
		nop //78
		nop //79
		nop //7a
		nop //7b
		nop //7c
		nop //7d
		nop //7e
		nop //7f
		nop //80
		nop	//0
		nop	//1
		nop	//2
		nop	//3
		nop	//4
		nop	//5
		nop	//6
		nop	//7
		nop	//8
		nop	//9
		nop	//a
		nop	//b
		nop	//c
		nop	//d
		nop	//e
		nop	//f
		nop	//10
		nop	//11
		nop	//12
		nop	//13
		nop	//14
		nop	//15
		nop	//16
		nop	//17
		nop	//18
		nop	//19
		nop	//1a
		nop	//1b
		nop	//1c
		nop	//1d
		nop	//1e
		nop	//1f
		nop	//20
		nop	//21
		nop	//22
		nop	//23
		nop	//24
		nop	//25
		nop	//26
		nop	//27
		nop	//28
		nop	//29
		nop	//2a
		nop	//2b
		nop	//2c
		nop	//2d
		nop	//2e
		nop	//2f
		nop	//30
		nop	//31
		nop //32
		nop	//33
		nop	//34
		nop	//35
		nop	//36
		nop	//37
		nop	//38
		nop	//39
		nop	//3a
		nop	//3b
		nop	//3c
		nop	//3d
		nop	//3e
		nop	//3f
		nop	//40
		nop //41
		nop //42
		nop //43
		nop //45
		nop //46
		nop //47
		nop //48
		nop //49
		nop //4a
		nop //4b
		nop //4c
		nop //4d
		nop //4e
		nop //4f
		nop //50
		nop //51
		nop //52
		nop //53
		nop //54
		nop //55
		nop //56
		nop //57
		nop //58
		nop //59
		nop //5a
		nop //5b
		nop //5c
		nop //5d
		nop //5e
		nop //5f
		nop //60
		nop //61
		nop //62
		nop //63
		nop //64
		nop //65
		nop //66
		nop //67
		nop //68
		nop //69
		nop //6a
		nop //6b
		nop //6c
		nop //6d
		nop //6e
		nop //6f
		nop //70
		nop //71
		nop //72
		nop //73
		nop //74
		nop //75
		nop //76
		nop //77
		nop //78
		nop //79
		nop //7a
		nop //7b
		nop //7c
		nop //7d
		nop //7e
		nop //7f
		nop //80
		nop	//0
		nop	//1
		nop	//2
		nop	//3
		nop	//4
		nop	//5
		nop	//6
		nop	//7
		nop	//8
		nop	//9
		nop	//a
		nop	//b
		nop	//c
		nop	//d
		nop	//e
		nop	//f
		nop	//10
		nop	//11
		nop	//12
		nop	//13
		nop	//14
		nop	//15
		nop	//16
		nop	//17
		nop	//18
		nop	//19
		nop	//1a
		nop	//1b
		nop	//1c
		nop	//1d
		nop	//1e
		nop	//1f
		nop	//20
		nop	//21
		nop	//22
		nop	//23
		nop	//24
		nop	//25
		nop	//26
		nop	//27
		nop	//28
		nop	//29
		nop	//2a
		nop	//2b
		nop	//2c
		nop	//2d
		nop	//2e
		nop	//2f
		nop	//30
		nop	//31
		nop //32
		nop	//33
		nop	//34
		nop	//35
		nop	//36
		nop	//37
		nop	//38
		nop	//39
		nop	//3a
		nop	//3b
		nop	//3c
		nop	//3d
		nop	//3e
		nop	//3f
		nop	//40
		nop //41
		nop //42
		nop //43
		nop //45
		nop //46
		nop //47
		nop //48
		nop //49
		nop //4a
		nop //4b
		nop //4c
		nop //4d
		nop //4e
		nop //4f
		nop //50
		nop //51
		nop //52
		nop //53
		nop //54
		nop //55
		nop //56
		nop //57
		nop //58
		nop //59
		nop //5a
		nop //5b
		nop //5c
		nop //5d
		nop //5e
		nop //5f
		nop //60
		nop //61
		nop //62
		nop //63
		nop //64
		nop //65
		nop //66
		nop //67
		nop //68
		nop //69
		nop //6a
		nop //6b
		nop //6c
		nop //6d
		nop //6e
		nop //6f
		nop //70
		nop //71
		nop //72
		nop //73
		nop //74
		nop //75
		nop //76
		nop //77
		nop //78
		nop //79
		nop //7a
		nop //7b
		nop //7c
		nop //7d
		nop //7e
		nop //7f
		nop //80
		nop	//0
		nop	//1
		nop	//2
		nop	//3
		nop	//4
		nop	//5
		nop	//6
		nop	//7
		nop	//8
		nop	//9
		nop	//a
		nop	//b
		nop	//c
		nop	//d
		nop	//e
		nop	//f
		nop	//10
		nop	//11
		nop	//12
		nop	//13
		nop	//14
		nop	//15
		nop	//16
		nop	//17
		nop	//18
		nop	//19
		nop	//1a
		nop	//1b
		nop	//1c
		nop	//1d
		nop	//1e
		nop	//1f
		nop	//20
		nop	//21
		nop	//22
		nop	//23
		nop	//24
		nop	//25
		nop	//26
		nop	//27
		nop	//28
		nop	//29
		nop	//2a
		nop	//2b
		nop	//2c
		nop	//2d
		nop	//2e
		nop	//2f
		nop	//30
		nop	//31
		nop //32
		nop	//33
		nop	//34
		nop	//35
		nop	//36
		nop	//37
		nop	//38
		nop	//39
		nop	//3a
		nop	//3b
		nop	//3c
		nop	//3d
		nop	//3e
		nop	//3f
		nop	//40
		nop //41
		nop //42
		nop //43
		nop //45
		nop //46
		nop //47
		nop //48
		nop //49
		nop //4a
		nop //4b
		nop //4c
		nop //4d
		nop //4e
		nop //4f
		nop //50
		nop //51
		nop //52
		nop //53
		nop //54
		nop //55
		nop //56
		nop //57
		nop //58
		nop //59
		nop //5a
		nop //5b
		nop //5c
		nop //5d
		nop //5e
		nop //5f
		nop //60
		nop //61
		nop //62
		nop //63
		nop //64
		nop //65
		nop //66
		nop //67
		nop //68
		nop //69
		nop //6a
		nop //6b
		nop //6c
		nop //6d
		nop //6e
		nop //6f
		nop //70
		nop //71
		nop //72
		nop //73
		nop //74
		nop //75
		nop //76
		nop //77
		nop //78
		nop //79
		nop //7a
		nop //7b
		nop //7c
		nop //7d
		nop //7e
		nop //7f
		nop //80
		nop	//0
		nop	//1
		nop	//2
		nop	//3
		nop	//4
		nop	//5
		nop	//6
		nop	//7
		nop	//8
		nop	//9
		nop	//a
		nop	//b
		nop	//c
		nop	//d
		nop	//e
		nop	//f
		nop	//10
		nop	//11
		nop	//12
		nop	//13
		nop	//14
		nop	//15
		nop	//16
		nop	//17
		nop	//18
		nop	//19
		nop	//1a
		nop	//1b
		nop	//1c
		nop	//1d
		nop	//1e
		nop	//1f
		nop	//20
		nop	//21
		nop	//22
		nop	//23
		nop	//24
		nop	//25
		nop	//26
		nop	//27
		nop	//28
		nop	//29
		nop	//2a
		nop	//2b
		nop	//2c
		nop	//2d
		nop	//2e
		nop	//2f
		nop	//30
		nop	//31
		nop //32
		nop	//33
		nop	//34
		nop	//35
		nop	//36
		nop	//37
		nop	//38
		nop	//39
		nop	//3a
		nop	//3b
		nop	//3c
		nop	//3d
		nop	//3e
		nop	//3f
		nop	//40
		nop //41
		nop //42
		nop //43
		nop //45
		nop //46
		nop //47
		nop //48
		nop //49
		nop //4a
		nop //4b
		nop //4c
		nop //4d
		nop //4e
		nop //4f
		nop //50
		nop //51
		nop //52
		nop //53
		nop //54
		nop //55
		nop //56
		nop //57
		nop //58
		nop //59
		nop //5a
		nop //5b
		nop //5c
		nop //5d
		nop //5e
		nop //5f
		nop //60
		nop //61
		nop //62
		nop //63
		nop //64
		nop //65
		nop //66
		nop //67
		nop //68
		nop //69
		nop //6a
		nop //6b
		nop //6c
		nop //6d
		nop //6e
		nop //6f
		nop //70
		nop //71
		nop //72
		nop //73
		nop //74
		nop //75
		nop //76
		nop //77
		nop //78
		nop //79
		nop //7a
		nop //7b
		nop //7c
		nop //7d
		nop //7e
		nop //7f
		nop //80
		nop	//0
		nop	//1
		nop	//2
		nop	//3
		nop	//4
		nop	//5
		nop	//6
		nop	//7
		nop	//8
		nop	//9
		nop	//a
		nop	//b
		nop	//c
		nop	//d
		nop	//e
		nop	//f
		nop	//10
		nop	//11
		nop	//12
		nop	//13
		nop	//14
		nop	//15
		nop	//16
		nop	//17
		nop	//18
		nop	//19
		nop	//1a
		nop	//1b
		nop	//1c
		nop	//1d
		nop	//1e
		nop	//1f
		nop	//20
		nop	//21
		nop	//22
		nop	//23
		nop	//24
		nop	//25
		nop	//26
		nop	//27
		nop	//28
		nop	//29
		nop	//2a
		nop	//2b
		nop	//2c
		nop	//2d
		nop	//2e
		nop	//2f
		nop	//30
		nop	//31
		nop //32
		nop	//33
		nop	//34
		nop	//35
		nop	//36
		nop	//37
		nop	//38
		nop	//39
		nop	//3a
		nop	//3b
		nop	//3c
		nop	//3d
		nop	//3e
		nop	//3f
		nop	//40
		nop //41
		nop //42
		nop //43
		nop //45
		nop //46
		nop //47
		nop //48
		nop //49
		nop //4a
		nop //4b
		nop //4c
		nop //4d
		nop //4e
		nop //4f
		nop //50
		nop //51
		nop //52
		nop //53
		nop //54
		nop //55
		nop //56
		nop //57
		nop //58
		nop //59
		nop //5a
		nop //5b
		nop //5c
		nop //5d
		nop //5e
		nop //5f
		nop //60
		nop //61
		nop //62
		nop //63
		nop //64
		nop //65
		nop //66
		nop //67
		nop //68
		nop //69
		nop //6a
		nop //6b
		nop //6c
		nop //6d
		nop //6e
		nop //6f
		nop //70
		nop //71
		nop //72
		nop //73
		nop //74
		nop //75
		nop //76
		nop //77
		nop //78
		nop //79
		nop //7a
		nop //7b
		nop //7c
		nop //7d
		nop //7e
		nop //7f
		nop //80
		nop	//0
		nop	//1
		nop	//2
		nop	//3
		nop	//4
		nop	//5
		nop	//6
		nop	//7
		nop	//8
		nop	//9
		nop	//a
		nop	//b
		nop	//c
		nop	//d
		nop	//e
		nop	//f
		nop	//10
		nop	//11
		nop	//12
		nop	//13
		nop	//14
		nop	//15
		nop	//16
		nop	//17
		nop	//18
		nop	//19
		nop	//1a
		nop	//1b
		nop	//1c
		nop	//1d
		nop	//1e
		nop	//1f
		nop	//20
		nop	//21
		nop	//22
		nop	//23
		nop	//24
		nop	//25
		nop	//26
		nop	//27
		nop	//28
		nop	//29
		nop	//2a
		nop	//2b
		nop	//2c
		nop	//2d
		nop	//2e
		nop	//2f
		nop	//30
		nop	//31
		nop //32
		nop	//33
		nop	//34
		nop	//35
		nop	//36
		nop	//37
		nop	//38
		nop	//39
		nop	//3a
		nop	//3b
		nop	//3c
		nop	//3d
		nop	//3e
		nop	//3f
		nop	//40
		nop //41
		nop //42
		nop //43
		nop //45
		nop //46
		nop //47
		nop //48
		nop //49
		nop //4a
		nop //4b
		nop //4c
		nop //4d
		nop //4e
		nop //4f
		nop //50
		nop //51
		nop //52
		nop //53
		nop //54
		nop //55
		nop //56
		nop //57
		nop //58
		nop //59
		nop //5a
		nop //5b
		nop //5c
		nop //5d
		nop //5e
		nop //5f
		nop //60
		nop //61
		nop //62
		nop //63
		nop //64
		nop //65
		nop //66
		nop //67
		nop //68
		nop //69
		nop //6a
		nop //6b
		nop //6c
		nop //6d
		nop //6e
		nop //6f
		nop //70
		nop //71
		nop //72
		nop //73
		nop //74
		nop //75
		nop //76
		nop //77
		nop //78
		nop //79
		nop //7a
		nop //7b
		nop //7c
		nop //7d
		nop //7e
		nop //7f
		nop //80
		ret
	}
}
HANDLE Native_DuplicateHandleInProcess(wchar_t *pName,ULONG HandleType)
{
	THREAD_BASIC_INFORMATION tbi = {0};
	POBJECT_NAME_INFORMATION oni = {0};
	CLIENT_ID Cid = {0};
	OBJECT_ATTRIBUTES oa = {0};
	PSYSTEM_HANDLE_INFORMATION_EX buf = {0};
	PUNICODE_STRING pnb = 0;
	HANDLE hCProcess = INVALID_HANDLE_VALUE,TempHandle = INVALID_HANDLE_VALUE;
	NTSTATUS Status = 0;
	ULONG Reusable = 0x40960;
	BOOLEAN test = 0;
	InitializeObjectAttributes(&oa,0,0,0,0);
	__try
	{
SzMismatch:
		buf = (PSYSTEM_HANDLE_INFORMATION_EX)RtlAllocateHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,HEAP_ZERO_MEMORY |HEAP_GROWABLE,Reusable);
		Status = NtQuerySystemInformation(SystemHandleInformation,buf,Reusable,&Reusable);
		if(Status == 0xC0000004 )
		{
			if(RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)buf))
			{
				__asm jmp SzMismatch;			
			}
		}
		if(!NT_SUCCESS(Status))
		{
			RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)buf);
			return INVALID_HANDLE_VALUE;
		}
		for(Reusable = 0;Reusable < buf->NumberOfHandles;Reusable++)
		{
			if(buf->Information[Reusable].ProcessId != 4)
			{
				if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_PROCESS)
				{
					Cid.UniqueProcess = (PVOID)buf->Information[Reusable].ProcessId;
					Cid.UniqueThread = 0;
					Status = RtlAdjustPrivilege(20L,true,0,&test);
					Status = NtOpenProcess(&hCProcess,PROCESS_ALL_ACCESS,&oa,&Cid);
					Status = RtlAdjustPrivilege(20L,false,0,&test);
					if(hCProcess != INVALID_HANDLE_VALUE)
					{	
						pnb = (PUNICODE_STRING)RtlAllocateHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,HEAP_ZERO_MEMORY|HEAP_GROWABLE,0x1024);
						Status = NtQueryInformationProcess(hCProcess,ProcessImageFileName,(PVOID)pnb,0x1024,0);
						if(pnb->Buffer != NULL)
						{
							PWCHAR cpn = (PWCHAR)pnb->Buffer;
							USHORT cln = pnb->Length;
							do
							{
								cpn++;
								if(wcscmp(pName,cpn)== 0)
								{
									switch(HandleType)
									{
										case OB_TYPE_PROCESS:
											test = RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)pnb);
											test = RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)buf);
											return hCProcess;
										case OB_TYPE_THREAD :
											Reusable = 0;
											do
											{
												if(buf->Information[Reusable].ProcessId == (USHORT)Cid.UniqueProcess)
												{
													if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_THREAD)
													{
														Status = NtDuplicateObject(hCProcess,(PHANDLE)buf->Information[Reusable].Handle,NtCurrentProcess(),&TempHandle,0,0,DUPLICATE_SAME_ACCESS);
														Status = NtQueryInformationThread(TempHandle,ThreadBasicInformation,&tbi,sizeof(tbi),0);
														if(tbi.ClientId.UniqueProcess == (PVOID)Cid.UniqueProcess)
														{
															RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)pnb);
															RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)buf);
															NtClose(hCProcess);
															return TempHandle;
														}
													}
												}
												Reusable++;
											}while(Reusable != buf->NumberOfHandles);
										case OB_TYPE_WINDOW_STATION:
											Reusable = 0;
											do
											{
												if(buf->Information[Reusable].ProcessId == (USHORT)Cid.UniqueProcess)
												{
													if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_WINDOW_STATION)
													{
														Status = NtDuplicateObject(hCProcess,(PHANDLE)buf->Information[Reusable].Handle,NtCurrentProcess(),&TempHandle,0,0,DUPLICATE_SAME_ACCESS);
														if(TempHandle != INVALID_HANDLE_VALUE)
														{
															RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)pnb);
															RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)buf);
															NtClose(hCProcess);
															return TempHandle;
														}
													}
												}
												Reusable++;
											}while(Reusable != buf->NumberOfHandles);
										case OB_TYPE_DESKTOP:
											Reusable = 0;
											do
											{
												if(buf->Information[Reusable].ProcessId == (USHORT)Cid.UniqueProcess)
												{
													if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_DESKTOP)
													{
														Status = NtDuplicateObject(hCProcess,(PHANDLE)buf->Information[Reusable].Handle,NtCurrentProcess(),&TempHandle,0,0,DUPLICATE_SAME_ACCESS);
														if(TempHandle != INVALID_HANDLE_VALUE)
														{
															RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)pnb);
															RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)buf);
															NtClose(hCProcess);
															return TempHandle;
														}
													}
												}
												Reusable++;
											}while(Reusable != buf->NumberOfHandles);
										default :
											return INVALID_HANDLE_VALUE;
										}
								}
								cln--;
							}while(cln);
						}
					}
				}
			}
		}
		if(pnb)
		{
			RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)pnb);
		}
		if(buf)
		{
			RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)buf);
		}
		if(hCProcess)
		{
			NtClose(hCProcess);
		}
		if(TempHandle)
		{
			NtClose(TempHandle);
		}
	}
	__except(1)
	{
		if(pnb)
		{
			RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)pnb);
		}
		if(buf)
		{
			RtlFreeHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,(PVOID)buf);
		}
		if(hCProcess)
		{
			NtClose(hCProcess);
		}
		if(TempHandle)
		{
			NtClose(TempHandle);
		}
	}
	return INVALID_HANDLE_VALUE;
}
